/*
	Copyright (C) 2010 Salil Bhagurkar

	This file is part of salil64

	salil64 is free software: you can redistribute it and/or modify
	it under the terms of the GNU Lesser General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	salil64 is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public License
	along with salil64.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <bitmap.h>

/*
 * Intra page allocation
 * Get a page from the pagealloc (which will be set to allocated)
 * Set up a sub-bitmap at the start of the page that allows
 * allocation of a minimum of 64 Bytes and in multiples of 64 bytes
 */


#define KMALLOC_PAGE_SIGN 0xABAB9393CACA4F4F
#define KMALLOC_BLOCK_COUNT 64
#define KMALLOC_BLOCK_SIZE 64

static unsigned long computeFreeSize(unsigned long *bitmap, unsigned long nr)
{
	return (nr - countBit(bitmap, nr)) * KMALLOC_BLOCK_SIZE;
}

struct KmallocPage {
	unsigned long sign;
	unsigned long bitmap; //Maps 64 64 byte blocks
	unsigned long freeSize; //Maximum free memory available in this page
	struct KmallocPage *next, *prev;
};

struct KmallocPage *kmallocPages = NULL, *kmallocPagesTail = NULL;

/*
 * Initialize a page and add it to the list
 */
static void kmallocInitPage(struct KmallocPage *page)
{
	page->sign = KMALLOC_PAGE_SIGN;
	page->bitmap = 0;
	//Set the bit for this header
	setBit(&page->bitmap, 0);
	page->freeSize = computeFreeSize(&page->bitmap, KMALLOC_BLOCK_COUNT);
	page->next = page->prev = NULL;
}

/*
 * Find a page with enough free space from the list of pages
 */
static struct kmallocPage *kmallocFindPage(unsigned long size)
{
	struct KmallocPage *page;
	LIST_FOR(kmallocPages, page) {
		if(page->freeSize >= size)
			return page;
	}
	return NULL;
}

void *kmalloc(unsigned long size)
{
	//Find if there is any memory available in the page list
	struct KmallocPage *page = kmallocFindPage(size);

	//If none available, get a free page

}
